package com.ld.security.server.admin.modules.gl.util;

import com.ld.security.server.admin.modules.gl.entity.GlMockEntity;
import com.ld.security.server.admin.modules.gl.service.IGlMockService;
import com.ld.security.common.core.base.SuperVo;
import com.ld.security.common.core.exception.ApiException;
import com.ld.security.common.core.util.JsonUtil;
import com.ld.security.common.core.util.ReflectionUtil;
import com.ld.security.common.mybatis.base.entity.LabelMap;
import com.ld.security.common.mybatis.base.entity.SuperEntity;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.lang.reflect.Field;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;
import java.util.Map;

@Component
public class MockUtil {

    private static IGlMockService mockService;

    public static int save(GlMockEntity mockEntity) {
        return mockService.save(mockEntity);
    }

    public static <E> E getById(String id, Class<E> clazz, Class... classes) {
        GlMockEntity e = mockService.getById(id);
        ApiException.throw400(e == null, "没定义mock数据");
        String json = e.getContent();
        E obj = JsonUtil.toObject(json, clazz, classes);
        return obj;
    }

    /**
     * 特殊字段移除
     *
     * @param value
     */
    private static void removeValue(Object value) {


        if (value instanceof SuperVo) {
            for (Field field : ReflectionUtil.getAllDeclaredFields(value.getClass())) {
                Object val = ReflectionUtil.invokeGetter(value, field.getName());
                removeValue(val);
            }
        } else if (value instanceof Map) {
            Map map = (Map) value;
            map.forEach((x, y) -> {
                removeValue(y);
            });
        } else if (value instanceof Collection) {
            Collection cols = (Collection) value;
            cols.forEach(x -> {
                removeValue(x);
            });
        } else if (value instanceof SuperEntity) {
            SuperEntity e = (SuperEntity) value;
            e.setCrtTime(null);
            e.setUptTime(null);
            e.setId(null);
            if (value instanceof LabelMap) {
                LabelMap labelMap = (LabelMap) value;
                labelMap.setLabelMap(null);
            }
        }

    }

    public static <E> boolean eqList(List<E> xs, List<E> ys) {

        if(xs.size() != ys.size()){
            return false;
        }

        xs  = ReflectionUtil.clone(xs, List.class,xs.get(0).getClass());

        removeValue(xs);
        ys  = ReflectionUtil.clone(ys, List.class,ys.get(0).getClass());

        removeValue(ys);

        String a = JsonUtil.toJson(xs);
        String b = JsonUtil.toJson(ys);
        return a.equals(b);

    }

    public static <E> boolean eq(E x, E y) {
        return eqList(Arrays.asList(x),Arrays.asList(y));
    }

    @Autowired
    public void setMockService(IGlMockService mockService) {
        MockUtil.mockService = mockService;
    }
}
